package 基础;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@SpringBootTest
public class 代理ProxyTests {
    @Test
    void testCglibProxy(){//CGLIB
        //1.目标对象
        IHello h1=new HelloImpl();
        //2.创建CGLIB代理对象(基于第三方的CGLIB库中的API为目标类型创建子类类型对象)
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(HelloImpl.class);
        enhancer.setCallback(new MethodInterceptor() {//在这里进行功能增强
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("method start ...");
                Object result=method.invoke(h1,objects);//执行目标对象方法
                System.out.println("method end ...");
                return result;
            }
        });
        HelloImpl proxy=(HelloImpl)enhancer.create();
        proxy.doSayHello();
    }
    @Test
    void testJdkProxy(){//JDK代理
        //1.目标对象
        IHello h1=new HelloImpl();
        //2.创建JDK代理对象(基于反射包中的Proxy类型来创建)
        IHello proxy=(IHello) Proxy.newProxyInstance(
                h1.getClass().getClassLoader(),
                h1.getClass().getInterfaces(),
                new InvocationHandler(){//业务处理器(当调用代理对象的方法时会执行这个对象的invoke方法)
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //1)扩展业务
                        System.out.println("start....");
                        //2)调用目标对象方法
                        Object obj= method.invoke(h1,args);
                        //3)扩展业务
                        System.out.println("end....");
                        return obj;
                    }
                });
        //3.调用方法
        proxy.doSayHello();
    }

    @Test
    void testMyBatisJdkProxy(){//JDK代理
        //2.为 IHello接口创建JDK代理对象(基于反射包中的Proxy类型来创建)
        IHello proxy=(IHello)Proxy.newProxyInstance(
                IHello.class.getClassLoader(),
                new Class[]{IHello.class},
                new InvocationHandler(){//业务处理器(当调用代理对象的方法时会执行这个对象的invoke方法)
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //1)扩展业务
                        System.out.println("start....");
                        //2)调用目标对象方法
                        ///sqlSession.selectList(....)
                        //3)扩展业务
                        System.out.println("end....");
                        return null;
                    }
                });

        proxy.doSayHello();
    }
}
